package com.yutian.socketbio.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 更多内容可参考：https://www.cnblogs.com/yunlongaimeng/p/9470865.html
 * @author zhoulei7
 * @create 2020-09-14
 **/
public class HttpServer {
    private static Logger log = LoggerFactory.getLogger(HttpServer.class);

    public static void listen(int port) {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(port);
            log.info("启动服务器HttpServer，该服务将处理一个客户端的TCP连接请求（可将浏览器作为客户端请求连接，不需要任何入参），将返回html报文....");
            acceptAndReply(ss);
        } catch (IOException e) {
            log.error(e.getMessage(), e);

        } finally {
            // ServerSocket关闭之后，自然和它相关的输入输出流都会被它关闭
            if(null != ss){
                try {
                    ss.close();
                } catch (IOException e) {
                }
            }
        }
    }

    private static void acceptAndReply(ServerSocket ss) throws IOException {
        Socket s = ss.accept();
        try {
            log.info("客户端:"+s.getInetAddress().getLocalHost()+"已连接到服务器HttpServer");

            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            //读取客户端发送来的消息
            //注：这里读取一行就断开。但实际处理中，会继续等待读取更多客户端消息。
            //br.readLine()在读取客户端发送过来的消息时，由于客户端断线，而其操作系统的不同，
            //这里读取的结果不同：
            //当windows的客户端断开时，br.readLine会抛出异常
            //当linux的客户端断开时，br.readLine会返回null
            String mess = br.readLine();
            // 如浏览器访问该服务，则发来的消息内容是“GET / HTTP/1.1”
            log.info("客户端发来消息："+mess);

            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            String reply = htmlContent(mess);
            bw.write(reply);
            log.info("服务端回复消息："+reply);
            bw.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // Socket关闭之后，自然和它相关的输入输出流都会被它关闭
            if(null != s){
                try {
                    s.close();
                    log.info("服务端断开客户端连接");
                } catch (IOException e) {
                }
            }
        }
    }

    private static String htmlContent(String mess){
        return "HTTP/1.1 200 OK\r\n" +
                "Content-Type: text/html; charset=utf-8\r\n" +
                "\r\n" +
                "<html><head><meta charset=\"utf-8\"><title>测试</title></head><body><h1>这是响应报文</h1></body></html>\r\n";
    }
}
